/*
 *  Julian.cpp
 *  Calendar
 *
 *  Created by Fredrik Gustafsson on 10/12/10.
 *  Copyright 2010 Kungliga Tekniska Högskolan. All rights reserved.
 *
 */

#include "julian.h"

using namespace lab2;

Julian::Julian() {
	Gregorian* g = new Gregorian();
	*this = Julian(g);
}

Julian::Julian(int year,int month,int day) {
	assert_valid_date(year, month, day);
	curr_year = year;
	curr_month = month;
	curr_day = day;
}

Julian::Julian(const Date* d) {
	this->set_date_from_base(d->mod_julian_day());
}

Julian::Julian(const Date& d) {
	this->set_date_from_base(d.mod_julian_day());
}

Julian::Julian(const Gregorian* d) {
	this->set_date_from_base(d->mod_julian_day());
}

Julian::Julian(const Gregorian& d) {
	this->set_date_from_base(d.mod_julian_day());
}

const int Julian::mod_julian_day() const {
	int yr = curr_year, mo = curr_month, day = curr_day;
	double JMJD  = 2400000.5;
	
	if (mo <= 2) {
        yr--;
        mo += 12;
	}
    int B = 0;
    return int(365.25 * (yr + 4716)) + int(30.6001 * (mo + 1)) + day + B - 1524.5 - JMJD;
}

void Julian::set_date_from_base(int jd) {
	double JMJD  = 2400000.5;
	
	double Z;
    const double F = modf(jd + JMJD + 0.5, &Z);
    int A = int(Z);
    const int B = A + 1524;
    const int C = int((B - 122.1) / 365.25);
    const int D = int(365.25 * C);
    const int E = int((B - D) / 30.6001);
    curr_day = B - D - int(30.6001 * E) + F;
    if (E < 14) 
        curr_month = E - 1;
    else
        curr_month = E - 13;
    if (curr_month > 2)
        curr_year = C - 4716;
    else
        curr_year = C - 4715;
}

const int Julian::get_century_offset(int year) const {
	int century = (int)year / 100;
    return 7-((century + 3) % 7 );
}

bool Julian::leap_year(int year) const {
	return ((year % 4) ==0);
}
